package com.mxpio.erp.quality.policy;

import com.mxpio.erp.common.enums.InspectionEnums;
import com.mxpio.erp.common.enums.NoticeStatusEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.inventory.entity.FeedPlanNotice;
import com.mxpio.erp.common.inventory.entity.InvFlow;
import com.mxpio.erp.common.inventory.entity.WarehouseOrder;
import com.mxpio.erp.common.inventory.entity.WarehouseOrderLine;
import com.mxpio.erp.common.jpa.model.Notice;
import com.mxpio.erp.common.order.policy.AbstractNoticePolicy;
import com.mxpio.erp.common.order.policy.NoticeContext;
import com.mxpio.erp.common.purchase.entity.PurchaseOrder;
import com.mxpio.erp.common.quality.entity.*;
import com.mxpio.erp.common.technology.entity.Item;
import com.mxpio.erp.common.technology.entity.WorkShop;
import com.mxpio.erp.common.vo.OrderExcuteLineVo;
import com.mxpio.erp.common.workshop.entity.ManufactureOrder;
import com.mxpio.erp.common.workshop.entity.OutsourceOrder;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.security.entity.Dept;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


//库存质检验收单 执行策略
public class InventoryQualityOrderNoticePolicy extends AbstractNoticePolicy {
	private List<OrderExcuteLineVo> orderExcuteVos;

	public InventoryQualityOrderNoticePolicy(List<OrderExcuteLineVo> orderExcuteVos) {
		this.orderExcuteVos = orderExcuteVos;
	}
	
	@Override
	public void execute(NoticeContext context) {
		
	}

	@Override
	public void apply(NoticeContext context) {
		if(beforeExecute(context)) {
			execute(context);
			Notice notice = context.getEntity();
			List<OrderExcuteLineVo> orderExcuteVos = context.getOrderExcuteVos();
			Set<String> itemCodeSet = orderExcuteVos.stream().map(OrderExcuteLineVo::getItemCode).collect(Collectors.toSet());
			List<Item> items = JpaUtil.linq(Item.class).in("itemCode", itemCodeSet).list();
			Map<String, Item> itemMap = JpaUtil.index(items,"itemCode");//查询物料
			//需要把原批次数据做出库处理
			//自动生成仓单,并出库
			WarehouseOrder wo = null;
			int woLineNo = 0;
			for(OrderExcuteLineVo vo : orderExcuteVos){
				woLineNo++;
				if(wo == null){
					wo = new WarehouseOrder();
					wo.setAccessType("out");
					wo.setBpmnStatus(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode());
					wo.setCloseStatus(OrderStatusEnums.CloseStatus.OPEN.getStatusCode());
					wo.setOrderStatus(OrderStatusEnums.OrderStatus.FINISHED.getStatusCode());
					wo.setOrderDate(new Date());
					wo.setOriginBizNo(vo.getBizOrderNo());
					wo.setWhCode(notice.getWhCode());
					wo.setWoType(NoticeStatusEnums.NoticeType.IIA_OUT.getCode());
					wo.setOriginNoticeNo(notice.getNoticeNo());//关联noticeno字段
					wo.setExecuteTime(new Date());
					wo.setExecutor("8888");//自动化助手，默认指定用户
					JpaUtil.save(wo);
				}
				WarehouseOrderLine line = new WarehouseOrderLine();
				line.setWhCode(wo.getWhCode());
				line.setCloseStatus(OrderStatusEnums.CloseStatus.OPEN.getStatusCode());
				Item item = itemMap.get(vo.getItemCode());
				line.setItemCode(vo.getItemCode());
				if (item!=null){
					line.setItemGroupCode(item.getItemGroupCode());
					line.setItemName(item.getItemName());
					line.setItemSpec(item.getItemSpec());
					line.setUnitCode(item.getUnitCode());
					line.setDrawingNo(item.getDrawingNo());
				}
				line.setQuantity(vo.getQuantity());
				line.setBizNo(wo.getBizNo());
				line.setLineNo(woLineNo+"");
				line.setOriginBizNo(vo.getBizOrderNo());
				line.setOriginBizLineNo(vo.getBizOrderlineNo());
				line.setSort(woLineNo+"");
				line.setLotNo(vo.getLotNo());
				line.setSubLotIndex(vo.getSubLotIndex());
				line.setOriginNoticeNo(vo.getNoticeNo());
				line.setOriginNoticeLineNo(vo.getNoticeLineNo());
				JpaUtil.save(line);

				//自动执行，生成流水
				InvFlow inFlow = new InvFlow();
				inFlow.setAccessType(wo.getAccessType());
				inFlow.setItemCode(line.getItemCode());
				inFlow.setWhCode(wo.getWhCode());
				inFlow.setQuantity(line.getQuantity());
				inFlow.setMemo(wo.getMemo());
				inFlow.setOriginBizNo(wo.getOriginBizNo());
				inFlow.setOriginBizType(wo.getOriginBizType());
				inFlow.setOriginBizLineNo(line.getOriginBizLineNo());
				inFlow.setWoBizNo(wo.getBizNo());
				inFlow.setWoBizType(wo.getWoType());
				inFlow.setWoBizLineNo(line.getLineNo());
				inFlow.setLotNo(line.getLotNo());
				inFlow.setSubLotIndex(line.getSubLotIndex());//增加子批索引
				JpaUtil.save(inFlow);
			}


			for(OrderExcuteLineVo vo : orderExcuteVos){
				InspectionBill bill = new InspectionBill();
				bill.setBusiType(InspectionEnums.ISBusiType.Stock.getCode());
				bill.setCheckStatus(InspectionEnums.CheckStatus.PLAN.getCode());//计划
				if (notice instanceof InQualityOrder){
					bill.setOriginBizType(InspectionEnums.OriginBizType.PURCH.getCode());
					String feedPlanNoticeNo = ((InQualityOrder) notice).getFeedPlanNoticeNo();
					String bizOrderNo = notice.getBizOrderNo();//bizOrderNo 可能为采购订单号，也可能为送货计划编号
					if (StringUtils.isBlank(feedPlanNoticeNo)){
						PurchaseOrder purchaseOrder = JpaUtil.getOne(PurchaseOrder.class, bizOrderNo);
						if (purchaseOrder!=null){
							bill.setApplyOrgType(InspectionEnums.ApplyOrgType.SUPPLY.getCode());
							bill.setApplyOrgCode(purchaseOrder.getPnCode());
							bill.setApplyOrgName(purchaseOrder.getPnName());
						}
					}else{//存在送货计划单号的情况
						FeedPlanNotice feedPlanNotice = JpaUtil.getOne(FeedPlanNotice.class, feedPlanNoticeNo);
						if (feedPlanNotice!=null){
							bill.setApplyOrgType(InspectionEnums.ApplyOrgType.SUPPLY.getCode());
							bill.setApplyOrgCode(feedPlanNotice.getPnCode());
							bill.setApplyOrgName(feedPlanNotice.getPnName());
						}
					}
				}else if (notice instanceof MoInQualityOrder){
					bill.setOriginBizType(InspectionEnums.OriginBizType.MANF.getCode());
					String bizOrderNo = notice.getBizOrderNo();
					ManufactureOrder manufactureOrder = JpaUtil.getOne(ManufactureOrder.class, bizOrderNo);
					if (manufactureOrder!=null){
						bill.setApplyOrgType(InspectionEnums.ApplyOrgType.WORKSHOP.getCode());
						bill.setApplyOrgCode(manufactureOrder.getMainWorkshop());
						WorkShop one = JpaUtil.getOne(WorkShop.class, manufactureOrder.getMainWorkshop());
						if (one!=null){
							bill.setApplyOrgName(one.getWorkShopName());
						}
					}
				}else if (notice instanceof OoInQualityOrder){
					bill.setOriginBizType(InspectionEnums.OriginBizType.OUTS.getCode());
					String bizOrderNo = notice.getBizOrderNo();
					OutsourceOrder outsourceOrder = JpaUtil.getOne(OutsourceOrder.class, bizOrderNo);
					if (outsourceOrder!=null){
						bill.setApplyOrgType(InspectionEnums.ApplyOrgType.PROC.getCode());
						bill.setApplyOrgCode(outsourceOrder.getPnCode());
						bill.setApplyOrgName(outsourceOrder.getPnName());
					}
				}else if (notice instanceof InventoryQualityOrder){//库存质检验收单
					bill.setOriginBizType(InspectionEnums.OriginBizType.INVENTORY.getCode());
					String bizOrderNo = notice.getBizOrderNo();
					InventoryInspectApply inspectApply = JpaUtil.getOne(InventoryInspectApply.class, bizOrderNo);
					if (inspectApply!=null){
						bill.setApplyOrgType(InspectionEnums.ApplyOrgType.DEPT.getCode());
						if (StringUtils.isNotBlank(inspectApply.getCreateDept())){
							bill.setApplyOrgCode(inspectApply.getCreateDept());
							Dept dept = JpaUtil.linq(Dept.class).equal("deptCode",inspectApply.getCreateDept()).findOne();
							if (dept!=null){
								bill.setApplyOrgName(dept.getDeptName());
							}
						}
					}
				}
				bill.setOriginBizNo(vo.getBizOrderNo());
				bill.setOriginBizLineNo(vo.getBizOrderlineNo());
				bill.setOriginNoticeNo(vo.getNoticeNo());
				bill.setOriginNoticeLineNo(vo.getNoticeLineNo());
				String itemCode = vo.getItemCode();
				Item item = itemMap.get(itemCode);
				bill.setItemCode(itemCode);
				if (item!=null){
					bill.setItemName(item.getItemName());
					bill.setItemSpec(item.getItemSpec());
					bill.setUnitCode(item.getUnitCode());
					bill.setDrawingNo(item.getDrawingNo());
				}
				bill.setQuantity(vo.getQuantity());
				JpaUtil.save(bill);
			}
			afterExecute(context);
			notice.setNoticeStatus(NoticeStatusEnums.NoticeStatus.CONFIRM.getStatusCode());
			JpaUtil.update(notice);
		} else {
			if(CollectionUtils.isEmpty(context.getErrors())) {
				context.addError("前置校验不通过");
			}
		}

	}
	@Override
	public NoticeContext config(NoticeContext context) {
		context.setOrderExcuteVos(orderExcuteVos);
		return context;
	}

	@Override
	public boolean beforeExecute(NoticeContext context) {
		List<OrderExcuteLineVo> orderExcuteVos = context.getOrderExcuteVos();
		Notice notice = context.getEntity();
		// 库存数量控制
		for (OrderExcuteLineVo vo:orderExcuteVos){
			BigDecimal stock = context.getLotService().getStock(notice.getWhCode(), vo.getItemCode(), vo.getLotNo(),vo.getSubLotIndex(),false);//此处不再校验hold状态
			if(stock.compareTo(vo.getQuantity()) < 0) {
				context.addError("物料：" + vo.getItemCode() + "批次库存不足！可用库存已被使用。请检查数据！");
				return false;
			}
		}
		return true;
	}

	@Override
	public void afterExecute(NoticeContext context) {
		
	}
}
